package cn.demoncat.util.sms.zhuowang;

import cn.demoncat.util.lang.JsonUtil;
import cn.demoncat.util.lang.LogUtil;
import cn.demoncat.util.lang.constant.StringConstant;
import cn.demoncat.util.lang.entity.Result;
import cn.demoncat.util.lang.entity.SmsData;
import cn.demoncat.util.lang.msg.SmsLogMsg;
import cn.demoncat.util.lang.msg.SmsMsg;
import cn.demoncat.util.sms.SmsInterface;
import cn.demoncat.util.web.HttpClientUtil;
import cn.demoncat.util.web.UrlUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * 卓望短信服务
 *
 * @author 延晓磊
 * @since 2020年09月30日
 */
@Component("smsZhuowangUtil")
public class SmsZhuowangUtil implements SmsInterface {

    // 配置
    @Resource
    private SmsZhuowangProperties smsZhuowangProperties;

    // 批次手机号数量限制
    public static final int MAX_PHONES = 200;

    // 状态码-成功
    private static final String CODE_OK = "0000";
    // 状态码-频繁
    private static final String CODE_BUSY = "2003";

    // 平台地址
    private static String url = null;

    private static final Logger LOG = LogUtil.get(SmsZhuowangUtil.class);

    /**
     * 发送短信
     *
     * 注：如果手机号超过200条，会批量发送，但只返回最后一次发送的响应结果，这样就与服务端的流水号会不一致
     *
     * @param data		请求数据（引用传值）
     *
     * @return Result	处理后的结果[500请求失败,400发送出错,200发送成功]
     *
     * @author 延晓磊
     * @since 2020年09月30日
     */
    @Override
    public Result send(SmsData data) {
        LOG.info(SmsLogMsg.SEND_SMS, data.getAppName(), data.getTemplateId(), data.getPhone());

        // 清空回执编号、状态、消息
        data.setBizId(StringConstant.EMPTY);
        data.setCode(StringConstant.EMPTY);
        data.setMessage(StringConstant.EMPTY);

        // 发送短信
        if (data.getPhones().size() < MAX_PHONES) {
            // 单次
            return send(data, data.getPhones());
        }else {
            // 多次
            int size = MAX_PHONES / 2;
            int times = data.getPhones().size() % size == 0 ? data.getPhones().size()/size : data.getPhones().size()/size + 1;
            List<String> phones = new ArrayList<>(data.getPhones());
            Result result = null;
            for (int i = 0;  i < times; i++) {
                // 分批手机号
                if (i == times -1) {
                    result = send(data, phones.subList(i*size, phones.size()));
                }else {
                    result = send(data, phones.subList(i*size, (i+1)*size));
                }
                if (!Result.isSuccess(result)) {
                    // 出错停止
                    return result;
                }
            }
            return result;
        }
    }

    /**
     * 发送短信
     *
     * @param data
     * @param phones 批次手机号
     * @return
     *
     * @author 延晓磊
     *
     * @since 2019年7月16日
     */
    private Result send(SmsData data, Collection<String> phones) {
        JSONObject response;
        try {
            // 发送短信
            response = send(getUrl(), smsZhuowangProperties.getAccount(), smsZhuowangProperties.getPassword(), data.getTemplate(), phones, data.getParam());
        } catch (Exception e) {
            // 请求失败
            LOG.error(SmsLogMsg.SEND_SMS_ERROR_BEFORE, data.getAppName(), data.getTemplateId(), data.getPhone(), e);
            data.setMessage(e.getMessage());
            return Result.FAIL;
        }
        // 结果校验
        String code = response.getString("code");
        data.setCode(code);
        if (CODE_OK.equals(code)) {
            data.setBizId(response.getString("msgid"));
            return Result.SUCCESS;
        }else {
            LOG.error(SmsLogMsg.SEND_SMS_ERROR_AFTER, data.getAppName(), data.getTemplateId(), data.getPhone(), data.getParamText(), response);
            data.setMessage(SmsZhuowangConstant.CODE.get(code));
            if (CODE_BUSY.equals(code)) {
                return Result.error(SmsMsg.SMS_SEND_ERROR_LIMIT);
            }
            return Result.error(SmsMsg.SMS_SEND_ERROR);
        }
    }

    /**
     * 获取请求地址
     *
     * @return
     */
    private String getUrl(){
        if (url == null) {
            url = "http://" + smsZhuowangProperties.getUrl() + "/template/send";
        }
        return url;
    }

    /**
     * 发送短信
     *
     * @param url
     * @param username
     * @param password
     * @param templateId
     * @param phones
     * @param params
     * @return
     */
    public static JSONObject send(String url, String username, String password, String templateId, Collection<String> phones, String[] params){
        // 请求参数
        Map<String,Object> map = new HashMap<>();
        map.put("username", username);
        map.put("password", password);
        map.put("templateid", templateId);
        List<String> list = new ArrayList<>(phones.size());
        if (ArrayUtils.isEmpty(params)) {
            list.addAll(phones);
        }else{
            List<String> arr;
            for (String phone : phones) {
                arr = new ArrayList<>();
                arr.add(phone);
                Collections.addAll(arr, params);
                list.add(StringUtils.join(arr,"|"));
            }
        }
        map.put("content", list);
        // 发起请求
        return JsonUtil.parseObject(HttpClientUtil.doPostJson(url, UrlUtil.encode(JsonUtil.toStr(map))));
    }
}
